GiNZAの学習モデルモジュールが見つからない!?エラーと解決策・調べたことまとめ
地域限定のTipsをお話しようと思います。
栗きんとんと言えば数個まとめて箱に入っているものが売られているものですが、岐阜県のアンテナショップでは単品の栗きんとんが買えます。
単品の栗きんとんも美味しいのですが、栗きんとんを作る過程で生まれる「栗きんとんのおこげ」というものがこの世には存在します。それがかなり美味しいので、見かける機会があったら是非買ってみてください。
▲ 栗きんとんと聞いてこれしか浮かばなかった方は「岐阜 栗きんとん」でググってみてください
こんにちは。データアナリティクス事業本部 インテグレーション部 機械学習チームのShirotaです。
これは「 クラスメソッド 機械学習チーム アドベントカレンダー 2022 」12/14(水)の記事となっております。
前日 12/13(火)の記事は以下よりご覧ください。Vertex AI Workbenchのマネージドノートブックでカスタムコンテナを利用する、Google Cloudで機械学習をやる人には特に嬉しいカスタムコンテナに関するブログになっております。
自然言語処理強化月間 と銘打って私は今回のアドベントカレンダーを執筆しているのですが、今回は前回の裏話という名のトラブル解決までの小ネタ備忘録を残しておきたいと思います。
GiNZAの検証時、実は初手でこけていた
前回のアドベントカレンダーでは、難なくGiNZAが動いたよ!という体でブログを書いておりました。
すいません。実は初手でつまずいて数時間ずっと唸っていました。
何が起きていたのか、どうやって解決したのか、また解決した今調べてみたことを折角なので備忘録として残しておきたいと思います。
動かしたコードとエラーメッセージ
以下、実際に動かしたコードとエラーメッセージを載せておきます。
良かったらどこが間違っていたのか考えてみてください。
import spacy nlp = spacy.load('ja-ginza') doc = nlp('文書の形態素解析をしてみたよ') for sent in doc.sents: for token in sent: print( token.i, token.orth_, token.lemma_, token.norm_, token.morph.get("Reading"), token.pos_, token.morph.get("Inflection"), token.tag_, token.dep_, token.head.i, ) print('EOS')
ModuleNotFoundError: No module named 'ja-ginza'
ちなみに私はメッセージ通りのエラーだと思い、パッケージの存在確認をしたのでその結果も載せておきます。
pip list | grep ja-ginza ja-ginza 5.1.2 ja-ginza-electra 5.1.2
この情報を載せたことでだいぶ詰んだのではないかと思われます。
更におまけの話ですが、Google Colaboratory(以下 Colab)上でもローカル環境上でも同様のエラーが出ました。
ブログだと皆さんと対話して情報の追加をすることができないので、早速答えの方を公開したいと思います。
エラーの解決方法
ja-ginza
(ハイフン繋ぎ)を ja_ginza
(アンダースコア繋ぎ)に変えたところ、無事コードが動きました。
ここの解決に至るまでにかなりの時間を要してしまったのですが、(何なら自力で答えが見つからず、チームメンバーの nokomoro3 さんがひらめいてくれたお陰で解決しました。ありがとうございました!)
調べたこと
ここまででお話ししたかったことは話し終えたのですが、折角なのでこのモジュールやPythonパッケージを管理するリポジトリであるPython Package Index(以下 PyPI)について調べたことをまとめておきます。
ja_ginzaのモジュール情報
pip show ja_ginza
でモジュール情報を調べてみると以下のようになっていました。
Name: ja-ginza Version: 5.1.2 Summary: Japanese multi-task CNN trained on UD-Japanese BCCWJ r2.8 + GSK2014-A(2019). Assigns word2vec token vectors. Components: tok2vec, parser, ner, morphologizer, atteribute_ruler, compound_splitter, bunsetu_recognizer. Home-page: https://github.com/megagonlabs/ginza Author: Megagon Labs Tokyo. Author-email: [email protected] License: MIT License Location: /usr/local/lib/python3.8/dist-packages Requires: ginza, sudachidict-core, sudachipy, spacy Required-by:
ハイライトもしましたが、 ja-ginza となっています。ちなみに、冒頭に載せた通り pip list
の結果も ja-ginza でした。
これはどういうことなのか、と気になったのでPythonのパッケージ管理リポジトリであるPyPIについて調べてみたところ、以下のようなルールがあることが公式ドキュメントから分かりました。
PEP 508 に従えば、正当なプロジェクト名は以下の条件を満たさなければなりません: ASCII文字・数字・アンダースコア(_)・ハイフン(-)・ピリオド(.)だけを含むこと、かつ、 先頭と最後の文字がASCII文字ないし数字であること。 プロジェクト名の比較では、大文字小文字を区別せず、また、アンダースコア・ハイフン・ピリオドは何文字連続していても同じものとして扱います。例えば、あなたが cool-stuff という名前のプロジェクトを登録したなら、利用者がダウンロードしたり依存関係を宣言したりするのに、次に挙げる綴りのどれでも使うことができます: Cool-Stuff cool.stuff COOL_STUFF CoOl__-.-__sTuFF
つまり、インストール時に pip install ja-ginza
と pip install ja_ginza
は区別されず、エラーが発生することなくライブラリはインストールできてしまうのです。
また、今回はこの事例に当てはまるかは分かりませんが、PyPIでは意図せずパッケージ名がアンダースコアからハイフンに変更される事例があるようでした。
先ほど確認してみたモジュール情報には、モジュールが格納されているディレクトリが「Location」という項目に記載されていました。
実際に、ディレクトリを確認してみます。
ls -la /usr/local/lib/python3.8/dist-packages | grep ginza drwxr-xr-x 3 root root 4096 Dec 13 09:14 ginza drwxr-xr-x 2 root root 4096 Dec 13 09:14 ginza-5.1.2.dist-info drwxr-xr-x 4 root root 4096 Dec 13 09:14 ginza_transformers drwxr-xr-x 2 root root 4096 Dec 13 09:14 ginza_transformers-0.4.2.dist-info drwxr-xr-x 4 root root 4096 Dec 13 09:14 ja_ginza drwxr-xr-x 2 root root 4096 Dec 13 09:14 ja_ginza-5.1.2.dist-info drwxr-xr-x 4 root root 4096 Dec 13 09:14 ja_ginza_electra drwxr-xr-x 2 root root 4096 Dec 13 09:14 ja_ginza_electra-5.1.2.dist-info
この時点で、モジュール名は ja_ginza
になっています。
このため、ja-ginza
で呼び出そうとしたらそんなモジュールはないよ、と ModuleNotFoundError
が出て怒られていた訳でした。
Pythonのコーディング規約
そもそもPythonにおいては、import
でハイフンを使おうとするとシンタックスエラーが出ます。
これについて、Pythonコードのコーディング規約であるPEP8を調べてみると以下のような命名規則があり、ハイフンについては言及されていないもののアンダースコアの利用はできることになっている旨が記載されていました。
モジュールの名前は、全て小文字の短い名前にすべきです。読みやすくなるなら、アンダースコアをモジュール名に使っても構いません。
自戒と次回予告
今回のエラーですが、もしかしたらPythonのモジュール名に関するコーディング規約の知識があったりインストールしたモジュールの詳細情報を真っ先に調べていたらこんなに悩むことはなかったかもしれないな……と感じました。
次に似たようなエラーがあったり、同様のエラーで悩んでいる方がいた時にこのブログが何らかの一助となれば幸いです。
▲ 最高、天才、Genius
さて、今回この備忘録を書くに当たって私はあるネタを先送りにしてしまいました。
このままだとどんどこ先送りにしてしまうので前もって次回予告をしておこうと思います。
次回は「コサイン類似度」の話をしたいと思います。次回こそします。
明日の機械学習チームのアドベントカレンダーもどうぞお楽しみに!